﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace SmartPlant.WinCore.Helper
{
    public static class ObjectHelper
    {
        /// <summary>
        /// 获取动态对象的数据字典值。
        /// </summary>
        /// <param name="propertyInfos"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static List<SimpleModel<string, Dictionary<string, string>>> GetObjDic(IList<DynamicPropertyInfo> propertyInfos, IList values)
        {
            if (propertyInfos == null)
                throw new ArgumentNullException(nameof(propertyInfos));
            if (values == null)
                throw new ArgumentNullException(nameof(values));

            var result = new List<SimpleModel<string, Dictionary<string, string>>>();
            foreach (var item in values)//相当于有几行内容要更新
            {
                var simpleModel = new SimpleModel<string, Dictionary<string, string>>
                {
                    v2 = new Dictionary<string, string>()
                };
                foreach (var pi in propertyInfos.Where(x => x.IsReadOnly == false))
                {
                    var piValue = Reflect.GetPropValue(item, pi.PropertyName);
                    if (pi.PrimaryKey)//主键作为key,不会加到属性值的字典里
                    {
                        if (simpleModel.v1.IsNullOrEmpty())
                        {
                            simpleModel.v1 = piValue != null ? piValue.ToString() : "";
                        }
                        else
                        {
                            simpleModel.v1 = piValue != null ? "," + piValue.ToString() : ", ";
                        }
                    }
                    else
                    {
                        simpleModel.v2.Add(pi.PropertyName, piValue != null ? piValue.ToString() : "");//非主键加入属性值的dic
                    }
                }
                result.Add(simpleModel);
            }
            return result;
        }

        /// <summary>
        /// 深度克隆对象。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T CloneObject<T>(this T t) where T : class
        {
            T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
            PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                //判断值是否为空，如果空赋值为null见else
                if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    //如果convertsionType为nullable类，声明一个NullableConverter类，该类提供从Nullable类到基础基元类型的转换
                    NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
                    //将convertsionType转换为nullable对的基础基元类型
                    propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), nullableConverter.UnderlyingType), null);
                }
                else
                {
                    propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), propertyInfo.PropertyType), null);
                }
            }
            return model;
        }

        /// <summary>
        /// 克隆集合。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        /// <returns></returns>
        public static IList<T> CloneList<T>(this IList<T> tList) where T : class
        {
            IList<T> listNew = new List<T>();
            foreach (var item in tList)
            {
                T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
                PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    //判断值是否为空，如果空赋值为null见else
                    if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                    {
                        //如果convertsionType为nullable类，声明一个NullableConverter类，该类提供从Nullable类到基础基元类型的转换
                        NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
                        //将convertsionType转换为nullable对的基础基元类型
                        propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), nullableConverter.UnderlyingType), null);
                    }
                    else
                    {
                        propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), propertyInfo.PropertyType), null);
                    }
                }
                listNew.Add(model);
            }
            return listNew;
        }
    }
}
